package com.alcatel_lucent.osp.action;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.BlockingQueue;

import com.alcatel_lucent.osp.model.*;
import com.alcatel_lucent.osp.service.*;
import net.sf.cglib.core.CollectionUtils;
import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.SessionAware;
import org.apache.struts2.json.JSONException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import javax.servlet.http.HttpServletRequest;

@SuppressWarnings("serial")
public class NewRequestAction extends JSONAction implements SessionAware, ServletRequestAware {

    private Long category;
    private Long type;
    private String description;
    private String targetDate;
    private String reporter;

    @Autowired
    private RequestService requestService;
    @Autowired
    private UserService userService;


    @Value("${rd360.category}")
    private String rd360Category;

    @Value(("${rd360.jira.sync}"))
    private String jiraDataPost;

    @Autowired
    private JSONService jsonService;

    private Map<String, Object> session;

    private HttpServletRequest httpRequest;

    public static final String ATTR_PREFIX = "attr_";

    private Map<String, String> getRequestAttributes() {
        Map<String, String> attributes = new HashMap<String, String>();
        Map<String, String[]> parameters = httpRequest.getParameterMap();
        for (Map.Entry<String, String[]> parameter : parameters.entrySet()) {
            if (parameter.getKey().startsWith(ATTR_PREFIX)) {
                attributes.put(parameter.getKey(), StringUtils.join(parameter.getValue(), ","));
            }
        }
        return attributes;
    }

    @Override
    @Action("new-request")
    protected String performAction() throws Exception {
        log.info("copyList={}", httpRequest.getParameterValues("copyList[]"));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Request request = new Request();
        request.setCategory((Category) dao.retrieve(Category.class, category));
        request.setType((Type) dao.retrieve(Type.class, type));

        request.setDescription(description);
        request.setTargetDate(targetDate == null || targetDate.trim().isEmpty() ? null : sdf.parse(targetDate));
        request.setReportBy(userService.findUserByCSLorCIL(reporter));

        String[] copyList = httpRequest.getParameterValues("copyList[]");
        Collection<User> copyListUsers = userService.getAndSaveUsersByCSL(copyList);
        request.setCopyList(copyListUsers);
        //set request attributes
        request.setAttributes(getRequestAttributes());


        BlockingQueue<Attachment> attachmentList = (BlockingQueue<Attachment>) session.get(UploadAttachmentAction.UPLOAD_TOKEN_KEY);
        if (null != attachmentList) {
            // clear temp id in attachment
            for (Attachment attachment : attachmentList) attachment.setId(null);
            request.setAttachments(attachmentList);
            session.remove(UploadAttachmentAction.UPLOAD_TOKEN_KEY);
            session.remove(UploadAttachmentAction.TRANSIENT_ATTACHMENT_ID_KEY);
        }

        if (request.getCategory().getName().equalsIgnoreCase(rd360Category)) {

            if (ArrayUtils.contains(jiraDataPost.split("\\s*,\\s"), request.getType().getName())) {

                log.info("=========={} request {} type post data to jiya=========", request.getCategory().getName(), request.getType().getName());
                Map<String, String> postData = new HashMap<String, String>();
                postData.put(JSONServiceImpl.RESOURCE_NAME_KEY, JSONServiceImpl.POST_JIRA);
                postData.put("username", UserContext.getInstance().getUser().getCsl());
                postData.put("title", request.getDescription());
                postData.put("type", request.getType().getName());
                postData.put("priority", request.getAttributes().get("attr_Priority"));
                postData.put("content", request.get("attr_description"));

                JSON result = jsonService.getRemoteJSON(postData);
                log.info("=========={} request {} type post data to jiya and got result {}.=========",
                        new Object[]{request.getCategory().getName(), request.getType().getName(), result});
            } else { // set description for normal rd360 prject
                if (StringUtils.isEmpty(request.getDescription())) {
                    String description;
                    if (Arrays.asList("Disable a PWS", "Change EPM-based PWS to local").contains(request.getType().getName())) {
                        description = request.get("attr_extra_project_name");
                    } else {
                        description = request.get("attr_projectName") + "_" +
                                RequestServiceImpl.rd360ProgramTypeMapping.get(request.get("attr_projectType"));
                    }
                    request.setDescription(description);
                }
            }
        }
        requestService.createRequest(request);

        return SUCCESS;
    }

    public String getReporter() {
        return reporter;
    }

    public void setReporter(String reporter) {
        this.reporter = reporter;
    }

    public Long getCategory() {
        return category;
    }

    public void setCategory(Long category) {
        this.category = category;
    }

    public Long getType() {
        return type;
    }

    public void setType(Long type) {
        this.type = type;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getTargetDate() {
        return targetDate;
    }

    public void setTargetDate(String targetDate) {
        this.targetDate = targetDate;
    }

    public RequestService getRequestService() {
        return requestService;
    }

    public void setRequestService(RequestService requestService) {
        this.requestService = requestService;
    }

    /**
     * Sets the Map of session attributes in the implementing class.
     *
     * @param session a Map of HTTP session attribute name/value pairs.
     */
    @Override
    public void setSession(Map<String, Object> session) {
        this.session = session;
    }

    /**
     * Sets the HTTP request object in implementing classes.
     *
     * @param request the HTTP request.
     */
    @Override
    public void setServletRequest(HttpServletRequest request) {
        this.httpRequest = request;
    }
}


